package http

import (
	"net/http"
	"time"

	"gitee.com/mkwchecking/sr-core/net/http/session"
	"github.com/gin-gonic/gin"
)

type Options func(*HttpConfig)

type Conn struct {
	Host    string        `json:"host"`    // Host
	Port    int           `json:"port"`    // Port
	Timeout time.Duration `json:"timeout"` // Timeout (ms)
	SSL     *SSL          `json:"ssl"`     // SSL config
}

type SSL struct {
	Enable bool   `json:"enable"` // Enable SSL
	Cert   string `json:"cert"`   // Cert file/content
	Key    string `json:"key"`    // Key file/content
}

type HttpConfig struct {
	Conn

	Mode        string                 `json:"mode"`      // gin mode default debug
	Handler     http.Handler           `json:"-"`         // 自定义 handler,default gin
	Middlewares []gin.HandlerFunc      `json:"-"`         // 中间件 only for gin
	WhiteList   []string               `json:"whiteList"` // 白名单 only for gin
	Session     *session.SessionConfig `json:"session"`   // Session config
	Health      *Health                `json:"health"`    // Health check
	Cors        *Cors                  `json:"cors"`      // CORS
}

type Health struct {
	Enable       bool   `json:"enable"`       // Enable health check
	Path         string `json:"path"`         // Health check path default "/ping"
	Response     string `json:"response"`     // Health check response default "pong"
	ResponseCode int    `json:"responseCode"` // Health check response code default 200
}

type Cors struct {
	AllowOrigins  []string `json:"allowOrigins"`  // Allow origins [default "*"]
	AllowMethods  []string `json:"allowMethods"`  // Allow methods [default "GET,POST,PUT,DELETE","OPTIONS"]
	AllowHeaders  []string `json:"allowHeaders"`  // Allow headers [default "Origin, Content-Type, Content-Length, Accept-Encoding, $SESSION_KEY"]
	ExposeHeaders []string `json:"exposeHeaders"` // Expose headers
}

func defaultConfig() *HttpConfig {
	return &HttpConfig{
		Conn: Conn{
			Host: "0.0.0.0",
			Port: 8080,
		},
	}
}

func WithHost(host string) func(*HttpConfig) {
	return func(cfg *HttpConfig) {
		cfg.Host = host
	}
}
func WithPort(port int) func(*HttpConfig) {
	return func(cfg *HttpConfig) {
		cfg.Port = port
	}
}

func WithSSL(cert, key string) func(*HttpConfig) {
	return func(cfg *HttpConfig) {
		cfg.SSL = &SSL{
			Enable: true,
			Cert:   cert,
			Key:    key,
		}
	}
}

func WithMode(mode string) func(*HttpConfig) {
	return func(cfg *HttpConfig) {
		cfg.Mode = mode
	}
}

func WithHandler(handler http.Handler) func(*HttpConfig) {
	return func(cfg *HttpConfig) {
		cfg.Handler = handler
	}
}

func WithMiddlewares(middlewares ...gin.HandlerFunc) func(*HttpConfig) {
	return func(cfg *HttpConfig) {
		cfg.Middlewares = append(cfg.Middlewares, middlewares...)
	}
}
